<?php

use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Drupal\node\Entity\Node;
use Drupal\file\Entity\File;

class SuperApiController {

  public function getSuperApiData(Request $request) {
    try {
      $content = json_decode($request->getContent(), true);

      if (!isset($content['lan']) || !isset($content['content_type'])) {
        return new JsonResponse([
          'status' => false,
          'message' => 'Both "lan" and "content_type" are required.'
        ], 400);
      }

      $langcode = $content['lan'];
      [$content_type, $is_multi_node] = $content['content_type'];
      $original_langcode = $langcode;

      $normal_fields = $content['normal_field'] ?? [];
      $file_fields = $content['file/image'] ?? [];
      $paragraph_fields = $content['paragraph'] ?? [];
      $taxonomy_fields = $content['taxonomy'] ?? [];
      $conditions = $content['condition'] ?? [];

      // Query building
      $query = \Drupal::entityQuery('node')
        ->condition('type', $content_type)
        ->condition('status', 1)
        ->condition('langcode', $langcode);

      foreach ($conditions as $condition) {
        [$value, $field_name, $is_taxonomy] = $condition;
        $query->condition($field_name, $value);
      }

      $nids = $query->execute();

      $fallback = false;
      if (empty($nids) && $langcode !== 'en') {
        $fallback = true;
        $langcode = 'en';
        $query = \Drupal::entityQuery('node')
          ->condition('type', $content_type)
          ->condition('status', 1)
          ->condition('langcode', $langcode);

        foreach ($conditions as $condition) {
          [$value, $field_name, $is_taxonomy] = $condition;
          $query->condition($field_name, $value);
        }

        $nids = $query->execute();
      }

      if ($is_multi_node === 'no' && !empty($nids)) {
        $nids = [reset($nids)];
      }

      $nodes = Node::loadMultiple($nids);
      $results = [];

      foreach ($nodes as $node) {
        if ($node->hasTranslation($langcode)) {
          $node = $node->getTranslation($langcode);
        }

        $data = [
          'nid' => $node->id(),
          'langcode' => $langcode
        ];

        // Normal fields
        foreach ($normal_fields as $field_name => $is_multi) {
          if ($node->hasField($field_name)) {
            $values = $node->get($field_name)->getValue();
            $data[$field_name] = ($is_multi === 'yes') ? array_column($values, 'value') : ($values[0]['value'] ?? '');
          }
        }

        // File/Image fields
        foreach ($file_fields as $field_name => $is_multi) {
          if ($node->hasField($field_name)) {
            $items = $node->get($field_name)->getValue();
            $urls = [];
            foreach ($items as $item) {
              $fid = $item['target_id'] ?? null;
              if ($fid) {
                $file = File::load($fid);
                if ($file) {
                  $urls[] = \Drupal::service('file_url_generator')->generateAbsoluteString($file->getFileUri());
                }
              }
            }
            $data[$field_name] = ($is_multi === 'yes') ? $urls : ($urls[0] ?? '');
          }
        }

        // Paragraph fields
        foreach ($paragraph_fields as $field_name => $target_type) {
          if ($node->hasField($field_name)) {
            $refs = $node->get($field_name)->referencedEntities();
            $resolved = [];
            foreach ($refs as $ref) {
              if ($ref->hasTranslation($langcode)) {
                $ref = $ref->getTranslation($langcode);
              }
              $resolved[] = $this->extractEntityFields($ref, $langcode);
            }
            $data[$field_name] = $resolved;
          }
        }

        // Taxonomy fields
        foreach ($taxonomy_fields as $field_name => $target_type) {
          if ($node->hasField($field_name)) {
            $refs = $node->get($field_name)->referencedEntities();
            $resolved = [];
            foreach ($refs as $ref) {
              if ($ref->hasTranslation($langcode)) {
                $ref = $ref->getTranslation($langcode);
              }
              $resolved[] = $this->extractEntityFields($ref, $langcode);
            }
            $data[$field_name] = $resolved;
          }
        }

        $results[] = $data;
      }

      return new JsonResponse([
        'status' => true,
        'message' => $fallback ? 'Fallback to English as no data was found in the requested language.' : 'Data fetched successfully.',
        'data' => $results
      ]);

    } catch (\Exception $e) {
      return new JsonResponse([
        'status' => false,
        'message' => 'Error: ' . $e->getMessage()
      ], 500);
    }
  }

  private function extractEntityFields($entity, $langcode) {
    $output = ['id' => $entity->id()];

    foreach ($entity->getFields() as $field_name => $field) {
      if (strpos($field_name, 'field_') !== 0 || $field->isEmpty()) {
        continue;
      }

      $value = $field->getValue();

      if (isset($value[0]['target_id']) && $field->getFieldDefinition()->getType() === 'image') {
        $urls = [];
        foreach ($value as $val) {
          $file = File::load($val['target_id']);
          if ($file) {
            $urls[] = \Drupal::service('file_url_generator')->generateAbsoluteString($file->getFileUri());
          }
        }
        $output[$field_name] = count($urls) > 1 ? $urls : ($urls[0] ?? '');
      } elseif (isset($value[0]['value'])) {
        $output[$field_name] = count($value) > 1 ? array_column($value, 'value') : $value[0]['value'];
      }
    }

    return $output;
  }
}
